;;==========================================================================
;; Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
;;==========================================================================

    INCLUDE kxarm.h

    TEXTAREA

ip  RN  r12
sp  RN  r13
lr  RN  r14
pc  RN  r15
;============================================================
;           div routine
;============================================================
    EXPORT __rt_sdiv
__rt_sdiv
    B   x_divide

    EXPORT  __rt_udiv
__rt_udiv
    B   x_udivide

    EXPORT  ___umodsi3
___umodsi3
    MOV r2, r0
    MOV r0, r1
    MOV r1, r2
    B   x_uremainder

    EXPORT  ___udivsi3
___udivsi3
    MOV r2, r0
    MOV r0, r1
    MOV r1, r2
    B   x_udivide

    EXPORT  ___modsi3
___modsi3
    MOV r2, r0
    MOV r0, r1
    MOV r1, r2
    B   x_remainder

    EXPORT  ___divsi3
___divsi3
    MOV r2, r0
    MOV r0, r1
    MOV r1, r2
    B   x_divide

    EXPORT  x_divtest
x_divtest
    MOV pc,lr

    EXPORT  x_remainder
x_remainder
    STMFD   sp!,{lr}
    BL  x_divide
    MOV r0,r1
    LDMFD   sp!,{pc}

    EXPORT  x_uremainder
x_uremainder
    STMFD   sp!,{lr}
    BL  x_udivide
    MOV r0,r1
    LDMFD   sp!,{pc}
    IF 1
    EXPORT  __rt_sdiv64by64 ; for update
__rt_sdiv64by64
    stmdb    r13!,{r4-r7,r14}
    mov      r4,r0
    mov      r5,r1
    mov      r6,r2
    mov      r7,r3
__ll_sdiv1
    ands     r12,r7,#0x80000000
    bpl      pp1  ; (__ll_sdiv1 + 0x10)
    rsbs     r6,r6,#0
    rsc      r7,r7,#0
pp1 ;
    eors     r12,r12,r5,asr #32
    bcc      pp2  ; (__ll_sdiv1 + 0x20)
    rsbs     r4,r4,#0
    rsc      r5,r5,#0
pp2 ;
    mov      r0,#0
    mov      r1,#0
    mov      r3,r5
    mov      r2,r4
    teq      r7,#0
    teqeq    r6,#0
    beq      pp6    ;(__ll_sdiv1 + 0x90)
    movs     r14,#0
pp3 ;
    adds     r6,r6,r6
    adcs     r7,r7,r7
    bcs      pp4    ;(__ll_sdiv1 + 0x60)
    cmp      r7,r3
    cmpeq    r6,r2
    addls    r14,r14,#1
    bls      pp3    ;(__ll_sdiv1 + 0x40)
    adds     r14,r14,#0
pp4 ;
    movs     r7,r7,rrx
    mov      r6,r6,rrx
pp5 ;
    subs     r4,r2,r6
    sbcs     r5,r3,r7
    movcs    r3,r5
    movcs    r2,r4
    adcs     r0,r0,r0
    adc      r1,r1,r1
    movs     r7,r7,lsr #1
    mov      r6,r6,rrx
    subs     r14,r14,#1
    bge      pp5    ;(__ll_sdiv1 + 0x68)
pp6 ;
    movs     r12,r12,lsl #1
    bcc      pp7    ;(__ll_sdiv1 + 0xa0)
    rsbs     r0,r0,#0
    rsc      r1,r1,#0
pp7 ;
    movs     r12,r12,lsl #1
    bcc      pp8    ;(__ll_sdiv1 + 0xb0)
    rsbs     r2,r2,#0
    rsc      r3,r3,#0
pp8 ;
    ldmia    r13!,{r4-r7,pc}
    ENDIF
;=============================================================
    EXPORT  __rt_srem64by64 ; for update
__rt_srem64by64
    stmdb     sp!, {r4 - r7, r11, lr}  ; stmfd
    mov       r4, r0
    mov       r5, r1
    mov       r7, r3
    orrs      r3, r4, r5
    mov       r6, r2
    moveq     r0, #0
    moveq     r1, #0
    beq       pp346     ;  pc+8+116
    orrs      r3, r6, r7
    bne       pp347     ;  pc+8+44
    mov       r0, #3, 2  ; 0xC0000000 = 3221225472
    ldr       r11, [pc, #0x20]  ;  pc+8+32 = 1003848C
    mov       r3, #0
    mov       r2, #0
    mov       r1, #0
    orr       r0, r0, #0x94  ; 0x94 = 148
    mov       lr, pc
    mov       pc, r11
    mvn       r0, #0
    mvn       r1, #0
    b         pp346     ;  pc+8+64
    DCD 0xF000FE38  ; syscall may cause error
pp347
    mov       r0, r4
    mov       r1, r5
    mov       r2, r6
    mov       r3, r7
    bl        __rt_sdiv64by64  ; 100382E4
    mov       r3, r1
    mov       r2, r0
    mov       r1, r6
    mul       lr, r2, r7
    mul       r2, r3, r1
    add       r3, lr, r2
    umull     lr, r2, r0, r1
    mul       r1, r0, r1
    add       r3, r3, r2
    subs      r0, r4, r1
    sbc       r1, r5, r3
pp346
    ldmia     sp!, {r4 - r7, r11, lr}  ; ldmfd
    mov       pc, lr
;=============================================================
    IMPENTRY __rt_udiv64by64
    stmdb     sp!, {r4 - r8, r11, lr}  ; stmfd
    mov       r7, #0
    mov       r8, #0
    mov       r4, #1
    mov       lr, #0
    orrs      r11, r2, r3
    bne       pp318     ;  pc+8+44
    mov       r0, #3, 2  ; 0xC0000000 = 3221225472
    ldr       r11, [pc, #0x20]  ;  pc+8+32 = 10038224
    mov       r3, #0
    mov       r2, #0
    mov       r1, #0
    orr       r0, r0, #0x94  ; 0x94 = 148
    mov       lr, pc
    mov       pc, r11
    mvn       r0, #0
    mvn       r1, #0
    b         pp319     ;  pc+8+180
    DCD 0xF000FE38  ; syscall may cause error
pp318
    cmp       r3, r1
    bhi       pp320     ;  pc+8+128
    bcc       pp321     ;  pc+8+4
    cmp       r2, r0
    bhi       pp322     ;  pc+8+80
pp321
    and       r5, r2, #0
    and       r6, r3, #2, 2  ; 0x80000000 = 2147483648
    orrs      r11, r5, r6
    bne       pp323     ;  pc+8+44
    mov       r3, r3, lsl #1
    mov       lr, lr, lsl #1
    orr       r3, r3, r2, lsr #31
    orr       lr, lr, r4, lsr #31
    mov       r4, r4, lsl #1
    mov       r2, r2, lsl #1
    cmp       r3, r1
    bcc       pp321     ;  pc+8-52
    bhi       pp325     ;  pc+8+88
    cmp       r2, r0
    bls       pp321     ;  pc+8-64
    b         pp325     ;  pc+8+76
pp323
    subs      r0, r0, r2
    sbc       r1, r1, r3
    mov       r7, r4
    mov       r8, lr
    b         pp325     ;  pc+8+56
pp322
    cmp       r3, r1
    bhi       pp320     ;  pc+8+24
    bcc       pp330     ;  pc+8+4
    cmp       r2, r0
    bhi       pp320     ;  pc+8+12
pp330
    adds      r7, r4, r7
    adc       r8, lr, r8
    subs      r0, r0, r2
    sbc       r1, r1, r3
pp320
    mov       r2, r2, lsr #1
    mov       r11, r4, lsr #1
    orr       r2, r2, r3, lsl #31
    orr       r4, r11, lr, lsl #31
    mov       r3, r3, lsr #1
    mov       lr, lr, lsr #1
pp325
    orrs      r11, r4, lr
    bne       pp322     ;  pc+8-72
    mov       r0, r7
    mov       r1, r8
pp319
    ldmia     sp!, {r4 - r8, r11, lr}  ; ldmfd
    mov       pc, lr
;=============================================================
    IMPENTRY __rt_urem64by64
    stmdb     sp!, {r4 - r7, r11, lr}  ; stmfd
    mov       r4, r0
    mov       r5, r1
    mov       r7, r3
    orrs      r3, r4, r5
    mov       r6, r2
    moveq     r0, #0
    moveq     r1, #0
    beq       pp343     ;  pc+8+116
    orrs      r3, r6, r7
    bne       pp344     ;  pc+8+44
    mov       r0, #3, 2  ; 0xC0000000 = 3221225472
    ldr       r11, [pc, #0x20]  ;  pc+8+32 = 100383E8
    mov       r3, #0
    mov       r2, #0
    mov       r1, #0
    orr       r0, r0, #0x94  ; 0x94 = 148
    mov       lr, pc
    mov       pc, r11
    mvn       r0, #0
    mvn       r1, #0
    b         pp343     ;  pc+8+64
    DCD 0xF000FE38  ; syscall may cause error
pp344
    mov       r0, r4
    mov       r1, r5
    mov       r2, r6
    mov       r3, r7
    bl        __rt_udiv64by64  ; 100381DC
    mov       r3, r1
    mov       r2, r0
    mov       r1, r6
    mul       lr, r2, r7
    mul       r2, r3, r1
    add       r3, lr, r2
    umull     lr, r2, r0, r1
    mul       r1, r0, r1
    add       r3, r3, r2
    subs      r0, r4, r1
    sbc       r1, r5, r3
pp343
    ldmia     sp!, {r4 - r7, r11, lr}  ; ldmfd
    mov       pc, lr
;=============================================================
x_overflow
    MVN r0,#0
    MOV pc,lr

    EXPORT  x_udivide       ; /* r0 = r1 / r0; r1 = r1 % r0 */
x_udivide
    CMP r0,#1
    BCC x_overflow
    BEQ x_divide_l0
    MOV ip,#0
    MOVS    r1,r1
    BPL x_divide_l1
    ORR ip,ip,#0x20000000   ; /* ip bit 0x20000000 = -ve r1 */
    MOVS    r1,r1,lsr #1
    ORRCS   ip,ip,#0x10000000   ; /* ip bit 0x10000000 = bit 0 of r1 */
    B   x_divide_l1

x_divide_l0             ; /* r0 == 1 */
    MOV r0,r1
    MOV r1,#0
    MOV pc,lr

    EXPORT  x_divide        ; /* r0 = r1 / r0; r1 = r1 % r0 */
x_divide
    CMP r0,#1
    BCC x_overflow
    BEQ x_divide_l0
    ANDS    ip,r0,#0x80000000
    RSBMI   r0,r0,#0
    ANDS    r2,r1,#0x80000000
    EOR ip,ip,r2
    RSBMI   r1,r1,#0
    ORR ip,r2,ip,lsr #1 ; /* ip bit 0x40000000 = -ve division */
                ; /* ip bit 0x80000000 = -ve remainder */

x_divide_l1
    MOV r2,#1
    MOV r3,#0

    CMP r1,r0
    BCC x_divide_b0
    CMP r1,r0,lsl #1
    BCC x_divide_b1
    CMP r1,r0,lsl #2
    BCC x_divide_b2
    CMP r1,r0,lsl #3
    BCC x_divide_b3
    CMP r1,r0,lsl #4
    BCC x_divide_b4
    CMP r1,r0,lsl #5
    BCC x_divide_b5
    CMP r1,r0,lsl #6
    BCC x_divide_b6
    CMP r1,r0,lsl #7
    BCC x_divide_b7
    CMP r1,r0,lsl #8
    BCC x_divide_b8
    CMP r1,r0,lsl #9
    BCC x_divide_b9
    CMP r1,r0,lsl #10
    BCC x_divide_b10
    CMP r1,r0,lsl #11
    BCC x_divide_b11
    CMP r1,r0,lsl #12
    BCC x_divide_b12
    CMP r1,r0,lsl #13
    BCC x_divide_b13
    CMP r1,r0,lsl #14
    BCC x_divide_b14
    CMP r1,r0,lsl #15
    BCC x_divide_b15
    CMP r1,r0,lsl #16
    BCC x_divide_b16
    CMP r1,r0,lsl #17
    BCC x_divide_b17
    CMP r1,r0,lsl #18
    BCC x_divide_b18
    CMP r1,r0,lsl #19
    BCC x_divide_b19
    CMP r1,r0,lsl #20
    BCC x_divide_b20
    CMP r1,r0,lsl #21
    BCC x_divide_b21
    CMP r1,r0,lsl #22
    BCC x_divide_b22
    CMP r1,r0,lsl #23
    BCC x_divide_b23
    CMP r1,r0,lsl #24
    BCC x_divide_b24
    CMP r1,r0,lsl #25
    BCC x_divide_b25
    CMP r1,r0,lsl #26
    BCC x_divide_b26
    CMP r1,r0,lsl #27
    BCC x_divide_b27
    CMP r1,r0,lsl #28
    BCC x_divide_b28
    CMP r1,r0,lsl #29
    BCC x_divide_b29
    CMP r1,r0,lsl #30
    BCC x_divide_b30
    CMP r1,r0,lsl #31
    SUBHS   r1,r1,r0,lsl #31
    ADDHS   r3,r3,r2,lsl #31
    CMP r1,r0,lsl #30
    SUBHS   r1,r1,r0,lsl #30
    ADDHS   r3,r3,r2,lsl #30
x_divide_b30
    CMP r1,r0,lsl #29
    SUBHS   r1,r1,r0,lsl #29
    ADDHS   r3,r3,r2,lsl #29
x_divide_b29
    CMP r1,r0,lsl #28
    SUBHS   r1,r1,r0,lsl #28
    ADDHS   r3,r3,r2,lsl #28
x_divide_b28
    CMP r1,r0,lsl #27
    SUBHSS  r1,r1,r0,lsl #27
    ADDHS   r3,r3,r2,lsl #27
x_divide_b27
    CMP r1,r0,lsl #26
    SUBHS   r1,r1,r0,lsl #26
    ADDHS   r3,r3,r2,lsl #26
x_divide_b26
    CMP r1,r0,lsl #25
    SUBHS   r1,r1,r0,lsl #25
    ADDHS   r3,r3,r2,lsl #25
x_divide_b25
    CMP r1,r0,lsl #24
    SUBHS   r1,r1,r0,lsl #24
    ADDHS   r3,r3,r2,lsl #24
x_divide_b24
    CMP r1,r0,lsl #23
    SUBHS   r1,r1,r0,lsl #23
    ADDHS   r3,r3,r2,lsl #23
x_divide_b23
    CMP r1,r0,lsl #22
    SUBHS   r1,r1,r0,lsl #22
    ADDHS   r3,r3,r2,lsl #22
x_divide_b22
    CMP r1,r0,lsl #21
    SUBHS   r1,r1,r0,lsl #21
    ADDHS   r3,r3,r2,lsl #21
x_divide_b21
    CMP r1,r0,lsl #20
    SUBHS   r1,r1,r0,lsl #20
    ADDHS   r3,r3,r2,lsl #20
x_divide_b20
    CMP r1,r0,lsl #19
    SUBHS   r1,r1,r0,lsl #19
    ADDHS   r3,r3,r2,lsl #19
x_divide_b19
    CMP r1,r0,lsl #18
    SUBHS   r1,r1,r0,lsl #18
    ADDHS   r3,r3,r2,lsl #18
x_divide_b18
    CMP r1,r0,lsl #17
    SUBHS   r1,r1,r0,lsl #17
    ADDHS   r3,r3,r2,lsl #17
x_divide_b17
    CMP r1,r0,lsl #16
    SUBHS   r1,r1,r0,lsl #16
    ADDHS   r3,r3,r2,lsl #16
x_divide_b16
    CMP r1,r0,lsl #15
    SUBHS   r1,r1,r0,lsl #15
    ADDHS   r3,r3,r2,lsl #15
x_divide_b15
    CMP r1,r0,lsl #14
    SUBHS   r1,r1,r0,lsl #14
    ADDHS   r3,r3,r2,lsl #14
x_divide_b14
    CMP r1,r0,lsl #13
    SUBHS   r1,r1,r0,lsl #13
    ADDHS   r3,r3,r2,lsl #13
x_divide_b13
    CMP r1,r0,lsl #12
    SUBHS   r1,r1,r0,lsl #12
    ADDHS   r3,r3,r2,lsl #12
x_divide_b12
    CMP r1,r0,lsl #11
    SUBHS   r1,r1,r0,lsl #11
    ADDHS   r3,r3,r2,lsl #11
x_divide_b11
    CMP r1,r0,lsl #10
    SUBHS   r1,r1,r0,lsl #10
    ADDHS   r3,r3,r2,lsl #10
x_divide_b10
    CMP r1,r0,lsl #9
    SUBHS   r1,r1,r0,lsl #9
    ADDHS   r3,r3,r2,lsl #9
x_divide_b9
    CMP r1,r0,lsl #8
    SUBHS   r1,r1,r0,lsl #8
    ADDHS   r3,r3,r2,lsl #8
x_divide_b8
    CMP r1,r0,lsl #7
    SUBHS   r1,r1,r0,lsl #7
    ADDHS   r3,r3,r2,lsl #7
x_divide_b7
    CMP r1,r0,lsl #6
    SUBHS   r1,r1,r0,lsl #6
    ADDHS   r3,r3,r2,lsl #6
x_divide_b6
    CMP r1,r0,lsl #5
    SUBHS   r1,r1,r0,lsl #5
    ADDHS   r3,r3,r2,lsl #5
x_divide_b5
    CMP r1,r0,lsl #4
    SUBHS   r1,r1,r0,lsl #4
    ADDHS   r3,r3,r2,lsl #4
x_divide_b4
    CMP r1,r0,lsl #3
    SUBHS   r1,r1,r0,lsl #3
    ADDHS   r3,r3,r2,lsl #3
x_divide_b3
    CMP r1,r0,lsl #2
    SUBHS   r1,r1,r0,lsl #2
    ADDHS   r3,r3,r2,lsl #2
x_divide_b2
    CMP r1,r0,lsl #1
    SUBHS   r1,r1,r0,lsl #1
    ADDHS   r3,r3,r2,lsl #1
x_divide_b1
    CMP r1,r0
    SUBHS   r1,r1,r0
    ADDHS   r3,r3,r2
x_divide_b0

    TST ip,#0x20000000
    BNE x_udivide_l1
    MOV r0,r3
    CMP ip,#0
    RSBMI   r1,r1,#0
    MOVS    ip,ip,lsl #1
    RSBMI   r0,r0,#0
    MOV pc,lr

x_udivide_l1
    TST ip,#0x10000000
    MOV r1,r1,lsl #1
    ORRNE   r1,r1,#1
    MOV r3,r3,lsl #1
    CMP r1,r0
    SUBHS   r1,r1,r0
    ADDHS   r3,r3,r2
    MOV r0,r3
    MOV pc,lr

    EXPORT __rt_srsh
__rt_srsh
    cmp       r2, #0
    moveq     pc, lr
    cmp       r2, #0x20
    blt       shift31
    cmp       r2, #0x40
    blt       shift63
    mov       r1, r1, asr #32
    mov       r0, r1
    mov       pc, lr
shift63
    and       r2, r2, #0x1F
    mov       r0, r1, asr r2
    mov       r1, r1, asr #32
    mov       pc, lr
shift31
    mov       r0, r0, lsr r2
    rsb       r3, r2, #0x20
    orr       r0, r0, r1, lsl r3
    mov       r1, r1, asr r2
    mov       pc, lr


    END